
package hk.ces.oxfam.patch.patchs;

import hk.ces.oxfam.patch.DBPatch;
import hk.ces.oxfam.patch.db.result.ExcuteResult;
import hk.ces.oxfam.patch.db.sql.PreparedSQL;
import hk.ces.oxfam.patch.db.sql.SQLUtil;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author ReutyCheng
 */
public class B201011080001Patch implements DBPatch
{
  public String getName()
  {
    return "Re-generate B201011080001 Batch No. DB Patch";
  }

  public void patch(Connection connection) throws SQLException
  {
    int count = 0;
    
    List<Long> batchIdsInB201011080001 = this.getBatchIdsInB201011080001(connection);
    String maxBatchNoInB20101108 = this.getMaxBatchNoInB20101108(connection);

    Logger.getLogger(this.getClass()).debug("Total " + batchIdsInB201011080001.size() + " Batch(s) have the same Batch No. [B201011080001]");
    Logger.getLogger(this.getClass()).debug("Max Batch No in B20101108XXXX : " + maxBatchNoInB20101108);

    if (maxBatchNoInB20101108 == null)
    {
      Logger.getLogger(this.getClass()).debug("Max Batch No is null. Exit Patch");
      return;
    }

    NumberFormat numberFormat = NumberFormat.getIntegerInstance();

    NumberFormat batchNoFormat = NumberFormat.getInstance();
    batchNoFormat.setMaximumFractionDigits(0);
    batchNoFormat.setMinimumFractionDigits(0);
    batchNoFormat.setMaximumIntegerDigits(4);
    batchNoFormat.setMinimumIntegerDigits(4);
    batchNoFormat.setGroupingUsed(false);
    try
    {
      Long maxBatchNoLong = (Long) numberFormat.parse(maxBatchNoInB20101108.replace("B20101108", ""));

      Iterator<Long> iterator = batchIdsInB201011080001.iterator();
      if (iterator.hasNext())
      {
        Long batchId = iterator.next();
        Logger.getLogger(this.getClass()).debug("Should Ignore set Batch with new Batch No for the first Case[batchid=" + batchId + "]");
      }

      int index = 1;
      while (iterator.hasNext())
      {
        Long batchId = iterator.next();
        String newBatchNo = "B20101108" + batchNoFormat.format(maxBatchNoLong + index++);

        ExcuteResult excuteResult = this.updateBatchNo(connection, batchId, newBatchNo);
        count += excuteResult.getResultCount();
        Logger.getLogger(this.getClass()).debug("[" + excuteResult.getExcuteStatus() + "] Set Batch with new Batch No [batchid=" + batchId + ", newBatchNo=" + newBatchNo + "]");
      }
    }
    catch (ParseException ex)
    {
      Logger.getLogger(this.getClass()).fatal(ex.getMessage(), ex);
    }

    Logger.getLogger(this.getClass()).debug("Patch Completed[updatedCount=" + count + "]");
  }

  private String getMaxBatchNoInB20101108(Connection connection) throws SQLException
  {
    String sql = "select max(batchno) from batch where batchno like ?";
    Object[] params = new Object[]{"B20101108%"};
    String maxBatchNoInB20101108 = SQLUtil.single(connection, new PreparedSQL(sql, params), String.class);

    return maxBatchNoInB20101108;
  }

  private List<Long> getBatchIdsInB201011080001(Connection connection) throws SQLException
  {
    String sql = "select id from batch where batchno = ? order by id asc";
    Object[] params = new Object[]{"B201011080001"};
    List<Long> list = SQLUtil.certainColumn(connection, new PreparedSQL(sql, params), Long.class);

    return list;
  }

  private ExcuteResult updateBatchNo(Connection connection, Long batchId, String newBatchNo) throws SQLException
  {
    String sql = "update batch set batchno = ? where id = ?";
    Object[] params = new Object[]{newBatchNo, batchId};

    return SQLUtil.execute(connection, new PreparedSQL(sql, params));
  }
}
